home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 1.iso
/
toolbox
/
src
/
exampleCode
/
opengl
/
xlib
/
tlogo.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-11-11
|
52KB
|
1,802 lines
/*
* (c) Copyright 1993-94, Silicon Graphics, Inc.
* ALL RIGHTS RESERVED
*
* Permission to use, copy, modify, and distribute this software for
* any purpose and without fee is hereby granted, provided that the above
* copyright notice appear in all copies and that both the copyright notice
* and this permission notice appear in supporting documentation, and that
* the name of Silicon Graphics, Inc. not be used in advertising
* or publicity pertaining to distribution of the software without specific,
* written prior permission.
*
* THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
* AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
* GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
* SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
* KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
* LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
* THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
* POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
*
* U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
* (c)(1)(ii) of the Rights in Technical Data and Computer Software
* clause at DFARS 252.227-7013 and/or in similar or successor
* clauses in the FAR or the DOD or NASA FAR Supplement.
* Unpublished-- rights reserved under the copyright laws of the
* United States. Contractor/manufacturer is Silicon Graphics,
* Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
*
* OpenGL(TM) is a trademark of Silicon Graphics, Inc.
*/
#include <GL/glu.h>
#include <GL/glx.h>
#include <stdio.h>
#include <stdlib.h>
#include <X11/keysym.h>
#include <string.h>
#include <math.h>
#ifdef unix
#include <sys/times.h>
#include <sys/param.h>
#endif
#define BLACK 0
#define GRAY (1 << (indexBits - 1))
#define WHITE ((1 << indexBits) - 1)
#define PI 3.141592654
static int RGBA_SB_attributes[] = {
GLX_RGBA,
GLX_ACCUM_RED_SIZE, 1,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_DEPTH_SIZE, 1,
GLX_STENCIL_SIZE, 1,
None,
};
static int RGBA_DB_attributes[] = {
GLX_RGBA,
GLX_ACCUM_RED_SIZE, 1,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_DOUBLEBUFFER,
GLX_DEPTH_SIZE, 1,
GLX_STENCIL_SIZE, 1,
None,
};
static int CI_SB_attributes[] = {
GLX_DEPTH_SIZE, 1,
GLX_STENCIL_SIZE, 1,
None,
};
static int CI_DB_attributes[] = {
GLX_DOUBLEBUFFER,
GLX_DEPTH_SIZE, 1,
GLX_STENCIL_SIZE, 1,
None,
};
static Display *dpy;
static Colormap cmap;
static Window window;
static GLint indexBits;
static char *fontName
= "-adobe-helvetica-bold-r-normal--18-180-75-75-p-103-iso8859-1";
static long fontBase;
static long fontWidth, fontHeight;
static float black[3] = {0.0, 0.0, 0.0};
static float white[3] = {1.0, 1.0, 1.0};
static float gray[3] = {0.5, 0.5, 0.5};
static float blue[3] = {0.0, 0.0, 1.0};
static long W = 300, H = 300;
static float xRotation = 30.0, yRotation = 30.0;
static float zTranslation = -15.0;
static double plane[4] = {1.0, 0.0, -1.0, 0.0};
static GLint colorIndexes[3] = {0, 200, 255};
static long singleCylinder;
static long doubleCylinder;
static long elbow, logo;
static long imageComponents = 3;
static long dodither = 1;
static long lighting = 1;
static long twoside = 1;
static long depth = 1;
static long fog = 0;
static long rgb = 1;
static long clipPlane = 1;
static long doubleBuffer = 1;
static long clearMask = GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT;
static long polymode = GL_FRONT_AND_BACK;
static long capping;
static long culling;
static long cullface;
static long texturing;
static long jittering;
static long motionblur;
static long feedbackmode;
#define MAX_FEED 1048576 /* 4 meg worth of floats */
static GLfloat feedbackBuf[MAX_FEED];
static long decimation = 1; /* Decimate image into 1x1 subimages */
#define Bl 0x00
#define Wh 0xff
#define checkImageWidth 8
#define checkImageHeight 8
static unsigned char checkImage[3*checkImageWidth*checkImageHeight] = {
Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,
Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,
Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,
Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,
Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,
Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,
Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,
Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,
};
#define Rd 0xa40000ff
#define Wt 0xffffffff
#define brickImageWidth 16
#define brickImageHeight 16
static unsigned long brickImage[brickImageWidth*brickImageHeight] = {
Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd,
Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd,
Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd,
Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd,
Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt,
Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd,
Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd,
Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd,
Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd,
Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt,
Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd,
Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd,
Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd,
Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd,
Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt,
Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd
};
static unsigned char* image = checkImage;
static long imageHeight = checkImageHeight;
static long imageWidth = checkImageWidth;
static float decal[] = {
GL_DECAL,
};
static float modulate[] = {
GL_MODULATE,
};
static float repeat[] = {
GL_REPEAT,
};
static float nearest[] = {
GL_NEAREST,
};
static unsigned char stipple[4*32] = {
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x0F, 0xF0, 0x00,
0x00, 0x0F, 0xF0, 0x00,
0x00, 0x0F, 0xF0, 0x00,
0x00, 0x0F, 0xF0, 0x00,
0x00, 0x0F, 0xF0, 0x00,
0x00, 0x0F, 0xF0, 0x00,
0x00, 0x0F, 0xF0, 0x00,
0x00, 0x0F, 0xF0, 0x00,
0x00, 0x0F, 0xF0, 0x00,
0x00, 0x0F, 0xF0, 0x00,
0x00, 0x0F, 0xF0, 0x00,
0x00, 0x0F, 0xF0, 0x00,
0x00, 0x0F, 0xF0, 0x00,
0x00, 0x0F, 0xF0, 0x00,
0x00, 0x0F, 0xF0, 0x00,
0x00, 0x0F, 0xF0, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
};
static float tscp[18][2] = {
{0.0, 0.0}, {1.0, 0.0},
{0.0, .125}, {1.0, .125},
{0.0, .250}, {1.0, .25},
{0.0, .375}, {1.0, .375},
{0.0, .50}, {1.0, .50},
{0.0, .625}, {1.0, .625},
{0.0, .75}, {1.0, .75},
{0.0, .875}, {1.0, .875},
{0.0, 1.0}, {1.0, 1.0},
};
static float scp[18][3] = {
{1.000000, 0.000000, 0.000000}, {1.000000, 0.000000, 5.000000},
{0.707107, 0.707107, 0.000000}, {0.707107, 0.707107, 5.000000},
{0.000000, 1.000000, 0.000000}, {0.000000, 1.000000, 5.000000},
{-0.707107, 0.707107, 0.000000}, {-0.707107, 0.707107, 5.000000},
{-1.000000, 0.000000, 0.000000}, {-1.000000, 0.000000, 5.000000},
{-0.707107, -0.707107, 0.000000}, {-0.707107, -0.707107, 5.000000},
{0.000000, -1.000000, 0.000000}, {0.000000, -1.000000, 5.000000},
{0.707107, -0.707107, 0.000000}, {0.707107, -0.707107, 5.000000},
{1.000000, 0.000000, 0.000000}, {1.000000, 0.000000, 5.000000},
};
static float dcp[18][3] = {
{1.000000, 0.000000, 0.000000}, {1.000000, 0.000000, 7.000000},
{0.707107, 0.707107, 0.000000}, {0.707107, 0.707107, 7.000000},
{0.000000, 1.000000, 0.000000}, {0.000000, 1.000000, 7.000000},
{-0.707107, 0.707107, 0.000000}, {-0.707107, 0.707107, 7.000000},
{-1.000000, 0.000000, 0.000000}, {-1.000000, 0.000000, 7.000000},
{-0.707107, -0.707107, 0.000000}, {-0.707107, -0.707107, 7.000000},
{0.000000, -1.000000, 0.000000}, {0.000000, -1.000000, 7.000000},
{0.707107, -0.707107, 0.000000}, {0.707107, -0.707107, 7.000000},
{1.000000, 0.000000, 0.000000}, {1.000000, 0.000000, 7.000000},
};
static float ep[7][9][3] = {
{
{1.000000, 0.000000, 0.000000},
{0.707107, 0.707107, 0.000000},
{0.000000, 1.000000, 0.000000},
{-0.707107, 0.707107, 0.000000},
{-1.000000, 0.000000, 0.000000},
{-0.707107, -0.707107, 0.000000},
{0.000000, -1.000000, 0.000000},
{0.707107, -0.707107, 0.000000},
{1.000000, 0.000000, 0.000000},
},
{
{1.000000, 0.034074, 0.258819},
{0.707107, 0.717087, 0.075806},
{0.000000, 1.000000, 0.000000},
{-0.707107, 0.717087, 0.075806},
{-1.000000, 0.034074, 0.258819},
{-0.707107, -0.648939, 0.441832},
{0.000000, -0.931852, 0.517638},
{0.707107, -0.648939, 0.441832},
{1.000000, 0.034074, 0.258819},
},
{
{1.000000, 0.133975, 0.500000},
{0.707107, 0.746347, 0.146447},
{0.000000, 1.000000, 0.000000},
{-0.707107, 0.746347, 0.146447},
{-1.000000, 0.133975, 0.500000},
{-0.707107, -0.478398, 0.853553},
{0.000000, -0.732051, 1.000000},
{0.707107, -0.478398, 0.853553},
{1.000000, 0.133975, 0.500000},
},
{
{1.000000, 0.292893, 0.707107},
{0.707107, 0.792893, 0.207107},
{0.000000, 1.000000, 0.000000},
{-0.707107, 0.792893, 0.207107},
{-1.000000, 0.292893, 0.707107},
{-0.707107, -0.207107, 1.207107},
{0.000000, -0.414214, 1.414214},
{0.707107, -0.207107, 1.207107},
{1.000000, 0.292893, 0.707107},
},
{
{1.000000, 0.500000, 0.866025},
{0.707107, 0.853553, 0.253653},
{0.000000, 1.000000, 0.000000},
{-0.707107, 0.853553, 0.253653},
{-1.000000, 0.500000, 0.866025},
{-0.707107, 0.146447, 1.478398},
{0.000000, 0.000000, 1.732051},
{0.707107, 0.146447, 1.478398},
{1.000000, 0.500000, 0.866025},
},
{
{1.000000, 0.741181, 0.965926},
{0.707107, 0.924194, 0.282913},
{0.000000, 1.000000, 0.000000},
{-0.707107, 0.924194, 0.282913},
{-1.000000, 0.741181, 0.965926},
{-0.707107, 0.558168, 1.648939},
{0.000000, 0.482362, 1.931852},
{0.707107, 0.558168, 1.648939},
{1.000000, 0.741181, 0.965926},
},
{
{1.000000, 1.000000, 1.000000},
{0.707107, 1.000000, 0.292893},
{0.000000, 1.000000, 0.000000},
{-0.707107, 1.000000, 0.292893},
{-1.000000, 1.000000, 1.000000},
{-0.707107, 1.000000, 1.707107},
{0.000000, 1.000000, 2.000000},
{0.707107, 1.000000, 1.707107},
{1.000000, 1.000000, 1.000000},
},
};
static float en[7][9][3] = {
{
{1.000000, 0.000000, 0.000000},
{0.707107, 0.707107, 0.000000},
{0.000000, 1.000000, 0.000000},
{-0.707107, 0.707107, 0.000000},
{-1.000000, 0.000000, 0.000000},
{-0.707107, -0.707107, 0.000000},
{0.000000, -1.000000, 0.000000},
{0.707107, -0.707107, 0.000000},
{1.000000, 0.000000, 0.000000},
},
{
{1.000000, 0.000000, 0.000000},
{0.707107, 0.683013, -0.183013},
{0.000000, 0.965926, -0.258819},
{-0.707107, 0.683013, -0.183013},
{-1.000000, 0.000000, 0.000000},
{-0.707107, -0.683013, 0.183013},
{0.000000, -0.965926, 0.258819},
{0.707107, -0.683013, 0.183013},
{1.000000, 0.000000, 0.000000},
},
{
{1.000000, 0.000000, 0.000000},
{0.707107, 0.612372, -0.353553},
{0.000000, 0.866025, -0.500000},
{-0.707107, 0.612372, -0.353553},
{-1.000000, 0.000000, 0.000000},
{-0.707107, -0.612372, 0.353553},
{0.000000, -0.866025, 0.500000},
{0.707107, -0.612372, 0.353553},
{1.000000, 0.000000, 0.000000},
},
{
{1.000000, 0.000000, 0.000000},
{0.707107, 0.612372, -0.500000},
{0.000000, 0.707107, -0.707107},
{-0.707107, 0.500000, -0.500000},
{-1.000000, 0.000000, 0.000000},
{-0.707107, -0.500000, 0.500000},
{0.000000, -0.707107, 0.707107},
{0.707107, -0.500000, 0.500000},
{1.000000, 0.000000, 0.000000},
},
{
{1.000000, 0.000000, 0.000000},
{0.707107, 0.353553, -0.612372},
{0.000000, 0.500000, -0.866025},
{-0.707107, 0.353553, -0.612372},
{-1.000000, 0.000000, 0.000000},
{-0.707107, -0.353553, 0.612372},
{0.000000, -0.500000, 0.866025},
{0.707107, -0.353553, 0.612372},
{1.000000, 0.000000, 0.000000},
},
{
{1.000000, 0.000000, 0.000000},
{0.707107, 0.183013, -0.683013},
{0.000000, 0.258819, -0.965926},
{-0.707107, 0.183013, -0.683013},
{-1.000000, 0.000000, 0.000000},
{-0.707107, -0.183013, 0.683013},
{0.000000, -0.258819, 0.965926},
{0.707107, -0.183013, 0.683013},
{1.000000, 0.000000, 0.000000},
},
{
{1.000000, 0.000000, 0.000000},
{0.707107, 0.000000, -0.707107},
{0.000000, 0.000000, -1.000000},
{-0.707107, 0.000000, -0.707107},
{-1.000000, 0.000000, 0.000000},
{-0.707107, 0.000000, 0.707107},
{0.000000, 0.000000, 1.000000},
{0.707107, 0.000000, 0.707107},
{1.000000, 0.000000, 0.000000},
},
};
static float tep[7][9][2] = {
{
{0, 0.0},
{0.125, 0.0},
{0.25, 0.0},
{0.375, 0.0},
{0.5, 0.0},
{0.625, 0.0},
{0.75, 0.0},
{0.875, 0.0},
{1.0, 0.0},
},
{
{0, 0.16667},
{0.125, 0.16667},
{0.25, 0.16667},
{0.375, 0.16667},
{0.5, 0.16667},
{0.625, 0.16667},
{0.75, 0.16667},
{0.875, 0.16667},
{1.0, 0.16667},
},
{
{0, 0.33333},
{0.125, 0.33333},
{0.25, 0.33333},
{0.375, 0.33333},
{0.5, 0.33333},
{0.625, 0.33333},
{0.75, 0.33333},
{0.875, 0.33333},
{1.0, 0.33333},
},
{
{0, 0.5},
{0.125, 0.5},
{0.25, 0.5},
{0.375, 0.5},
{0.5, 0.5},
{0.625, 0.5},
{0.75, 0.5},
{0.875, 0.5},
{1.0, 0.5},
},
{
{0, 0.6667},
{0.125, 0.6667},
{0.25, 0.6667},
{0.375, 0.6667},
{0.5, 0.6667},
{0.625, 0.6667},
{0.75, 0.6667},
{0.875, 0.6667},
{1.0, 0.6667},
},
{
{0, 0.83333},
{0.125, 0.83333},
{0.25, 0.83333},
{0.375, 0.83333},
{0.5, 0.83333},
{0.625, 0.83333},
{0.75, 0.83333},
{0.875, 0.83333},
{1.0, 0.83333},
},
{
{0, 1.0},
{0.125, 1.0},
{0.25, 1.0},
{0.375, 1.0},
{0.5, 1.0},
{0.625, 1.0},
{0.75, 1.0},
{0.875, 1.0},
{1.0, 1.0},
}
};
static void Build_single_cylinder(void)
{
float st[2];
glNewList(singleCylinder, GL_COMPILE);
glBegin(GL_TRIANGLE_STRIP);
glNormal3fv(scp[0]); glTexCoord2fv(tscp[0]); glVertex3fv(scp[0]);
glNormal3fv(scp[0]); glTexCoord2fv(tscp[1]); glVertex3fv(scp[1]);
glNormal3fv(scp[2]); glTexCoord2fv(tscp[2]); glVertex3fv(scp[2]);
glNormal3fv(scp[2]); glTexCoord2fv(tscp[3]); glVertex3fv(scp[3]);
glNormal3fv(scp[4]); glTexCoord2fv(tscp[4]); glVertex3fv(scp[4]);
glNormal3fv(scp[4]); glTexCoord2fv(tscp[5]); glVertex3fv(scp[5]);
glNormal3fv(scp[6]); glTexCoord2fv(tscp[6]); glVertex3fv(scp[6]);
glNormal3fv(scp[6]); glTexCoord2fv(tscp[7]); glVertex3fv(scp[7]);
glNormal3fv(scp[8]); glTexCoord2fv(tscp[8]); glVertex3fv(scp[8]);
glNormal3fv(scp[8]); glTexCoord2fv(tscp[9]); glVertex3fv(scp[9]);
glNormal3fv(scp[10]); glTexCoord2fv(tscp[10]); glVertex3fv(scp[10]);
glNormal3fv(scp[10]); glTexCoord2fv(tscp[11]); glVertex3fv(scp[11]);
glNormal3fv(scp[12]); glTexCoord2fv(tscp[12]); glVertex3fv(scp[12]);
glNormal3fv(scp[12]); glTexCoord2fv(tscp[13]); glVertex3fv(scp[13]);
glNormal3fv(scp[14]); glTexCoord2fv(tscp[14]); glVertex3fv(scp[14]);
glNormal3fv(scp[14]); glTexCoord2fv(tscp[15]); glVertex3fv(scp[15]);
glNormal3fv(scp[16]); glTexCoord2fv(tscp[16]); glVertex3fv(scp[16]);
glNormal3fv(scp[16]); glTexCoord2fv(tscp[17]); glVertex3fv(scp[17]);
glEnd();
glEndList();
}
static void Build_double_cylinder(void)
{
float st[2];
glNewList(doubleCylinder, GL_COMPILE);
glBegin(GL_TRIANGLE_STRIP);
glNormal3fv(dcp[0]); glTexCoord2fv(tscp[0]); glVertex3fv(dcp[0]);
glNormal3fv(dcp[0]); glTexCoord2fv(tscp[1]); glVertex3fv(dcp[1]);
glNormal3fv(dcp[2]); glTexCoord2fv(tscp[2]); glVertex3fv(dcp[2]);
glNormal3fv(dcp[2]); glTexCoord2fv(tscp[3]); glVertex3fv(dcp[3]);
glNormal3fv(dcp[4]); glTexCoord2fv(tscp[4]); glVertex3fv(dcp[4]);
glNormal3fv(dcp[4]); glTexCoord2fv(tscp[5]); glVertex3fv(dcp[5]);
glNormal3fv(dcp[6]); glTexCoord2fv(tscp[6]); glVertex3fv(dcp[6]);
glNormal3fv(dcp[6]); glTexCoord2fv(tscp[7]); glVertex3fv(dcp[7]);
glNormal3fv(dcp[8]); glTexCoord2fv(tscp[8]); glVertex3fv(dcp[8]);
glNormal3fv(dcp[8]); glTexCoord2fv(tscp[9]); glVertex3fv(dcp[9]);
glNormal3fv(dcp[10]); glTexCoord2fv(tscp[10]); glVertex3fv(dcp[10]);
glNormal3fv(dcp[10]); glTexCoord2fv(tscp[11]); glVertex3fv(dcp[11]);
glNormal3fv(dcp[12]); glTexCoord2fv(tscp[12]); glVertex3fv(dcp[12]);
glNormal3fv(dcp[12]); glTexCoord2fv(tscp[13]); glVertex3fv(dcp[13]);
glNormal3fv(dcp[14]); glTexCoord2fv(tscp[14]); glVertex3fv(dcp[14]);
glNormal3fv(dcp[14]); glTexCoord2fv(tscp[15]); glVertex3fv(dcp[15]);
glNormal3fv(dcp[16]); glTexCoord2fv(tscp[16]); glVertex3fv(dcp[16]);
glNormal3fv(dcp[16]); glTexCoord2fv(tscp[17]); glVertex3fv(dcp[17]);
glEnd();
glEndList();
}
static void Build_elbow(void)
{
float st[2];
glNewList(elbow, GL_COMPILE);
glBegin(GL_TRIANGLE_STRIP);
glNormal3fv(en[0][0]); glTexCoord2fv(tep[0][0]); glVertex3fv(ep[0][0]);
glNormal3fv(en[1][0]); glTexCoord2fv(tep[1][0]); glVertex3fv(ep[1][0]);
glNormal3fv(en[0][1]); glTexCoord2fv(tep[0][1]); glVertex3fv(ep[0][1]);
glNormal3fv(en[1][1]); glTexCoord2fv(tep[1][1]); glVertex3fv(ep[1][1]);
glNormal3fv(en[0][2]); glTexCoord2fv(tep[0][2]); glVertex3fv(ep[0][2]);
glNormal3fv(en[1][2]); glTexCoord2fv(tep[1][2]); glVertex3fv(ep[1][2]);
glNormal3fv(en[0][3]); glTexCoord2fv(tep[0][3]); glVertex3fv(ep[0][3]);
glNormal3fv(en[1][3]); glTexCoord2fv(tep[1][3]); glVertex3fv(ep[1][3]);
glNormal3fv(en[0][4]); glTexCoord2fv(tep[0][4]); glVertex3fv(ep[0][4]);
glNormal3fv(en[1][4]); glTexCoord2fv(tep[1][4]); glVertex3fv(ep[1][4]);
glNormal3fv(en[0][5]); glTexCoord2fv(tep[0][5]); glVertex3fv(ep[0][5]);
glNormal3fv(en[1][5]); glTexCoord2fv(tep[1][5]); glVertex3fv(ep[1][5]);
glNormal3fv(en[0][6]); glTexCoord2fv(tep[0][6]); glVertex3fv(ep[0][6]);
glNormal3fv(en[1][6]); glTexCoord2fv(tep[1][6]); glVertex3fv(ep[1][6]);
glNormal3fv(en[0][7]); glTexCoord2fv(tep[0][7]); glVertex3fv(ep[0][7]);
glNormal3fv(en[1][7]); glTexCoord2fv(tep[1][7]); glVertex3fv(ep[1][7]);
glNormal3fv(en[0][8]); glTexCoord2fv(tep[0][8]); glVertex3fv(ep[0][8]);
glNormal3fv(en[1][8]); glTexCoord2fv(tep[1][8]); glVertex3fv(ep[1][8]);
glEnd();
glBegin(GL_TRIANGLE_STRIP);
glNormal3fv(en[1][0]); glTexCoord2fv(tep[1][0]); glVertex3fv(ep[1][0]);
glNormal3fv(en[2][0]); glTexCoord2fv(tep[2][0]); glVertex3fv(ep[2][0]);
glNormal3fv(en[1][1]); glTexCoord2fv(tep[1][1]); glVertex3fv(ep[1][1]);
glNormal3fv(en[2][1]); glTexCoord2fv(tep[2][1]); glVertex3fv(ep[2][1]);
glNormal3fv(en[1][2]); glTexCoord2fv(tep[1][2]); glVertex3fv(ep[1][2]);
glNormal3fv(en[2][2]); glTexCoord2fv(tep[2][2]); glVertex3fv(ep[2][2]);
glNormal3fv(en[1][3]); glTexCoord2fv(tep[1][3]); glVertex3fv(ep[1][3]);
glNormal3fv(en[2][3]); glTexCoord2fv(tep[2][3]); glVertex3fv(ep[2][3]);
glNormal3fv(en[1][4]); glTexCoord2fv(tep[1][4]); glVertex3fv(ep[1][4]);
glNormal3fv(en[2][4]); glTexCoord2fv(tep[2][4]); glVertex3fv(ep[2][4]);
glNormal3fv(en[1][5]); glTexCoord2fv(tep[1][5]); glVertex3fv(ep[1][5]);
glNormal3fv(en[2][5]); glTexCoord2fv(tep[2][5]); glVertex3fv(ep[2][5]);
glNormal3fv(en[1][6]); glTexCoord2fv(tep[1][6]); glVertex3fv(ep[1][6]);
glNormal3fv(en[2][6]); glTexCoord2fv(tep[2][6]); glVertex3fv(ep[2][6]);
glNormal3fv(en[1][7]); glTexCoord2fv(tep[1][7]); glVertex3fv(ep[1][7]);
glNormal3fv(en[2][7]); glTexCoord2fv(tep[2][7]); glVertex3fv(ep[2][7]);
glNormal3fv(en[1][8]); glTexCoord2fv(tep[1][8]); glVertex3fv(ep[1][8]);
glNormal3fv(en[2][8]); glTexCoord2fv(tep[2][8]); glVertex3fv(ep[2][8]);
glEnd();
glBegin(GL_TRIANGLE_STRIP);
glNormal3fv(en[2][0]); glTexCoord2fv(tep[2][0]); glVertex3fv(ep[2][0]);
glNormal3fv(en[3][0]); glTexCoord2fv(tep[3][0]); glVertex3fv(ep[3][0]);
glNormal3fv(en[2][1]); glTexCoord2fv(tep[2][1]); glVertex3fv(ep[2][1]);
glNormal3fv(en[3][1]); glTexCoord2fv(tep[3][1]); glVertex3fv(ep[3][1]);
glNormal3fv(en[2][2]); glTexCoord2fv(tep[2][2]); glVertex3fv(ep[2][2]);
glNormal3fv(en[3][2]); glTexCoord2fv(tep[3][2]); glVertex3fv(ep[3][2]);
glNormal3fv(en[2][3]); glTexCoord2fv(tep[2][3]); glVertex3fv(ep[2][3]);
glNormal3fv(en[3][3]); glTexCoord2fv(tep[3][3]); glVertex3fv(ep[3][3]);
glNormal3fv(en[2][4]); glTexCoord2fv(tep[2][4]); glVertex3fv(ep[2][4]);
glNormal3fv(en[3][4]); glTexCoord2fv(tep[3][4]); glVertex3fv(ep[3][4]);
glNormal3fv(en[2][5]); glTexCoord2fv(tep[2][5]); glVertex3fv(ep[2][5]);
glNormal3fv(en[3][5]); glTexCoord2fv(tep[3][5]); glVertex3fv(ep[3][5]);
glNormal3fv(en[2][6]); glTexCoord2fv(tep[2][6]); glVertex3fv(ep[2][6]);
glNormal3fv(en[3][6]); glTexCoord2fv(tep[3][6]); glVertex3fv(ep[3][6]);
glNormal3fv(en[2][7]); glTexCoord2fv(tep[2][7]); glVertex3fv(ep[2][7]);
glNormal3fv(en[3][7]); glTexCoord2fv(tep[3][7]); glVertex3fv(ep[3][7]);
glNormal3fv(en[2][8]); glTexCoord2fv(tep[2][8]); glVertex3fv(ep[2][8]);
glNormal3fv(en[3][8]); glTexCoord2fv(tep[3][8]); glVertex3fv(ep[3][8]);
glEnd();
glBegin(GL_TRIANGLE_STRIP);
glNormal3fv(en[3][0]); glTexCoord2fv(tep[3][0]); glVertex3fv(ep[3][0]);
glNormal3fv(en[4][0]); glTexCoord2fv(tep[4][0]); glVertex3fv(ep[4][0]);
glNormal3fv(en[3][1]); glTexCoord2fv(tep[3][1]); glVertex3fv(ep[3][1]);
glNormal3fv(en[4][1]); glTexCoord2fv(tep[4][1]); glVertex3fv(ep[4][1]);
glNormal3fv(en[3][2]); glTexCoord2fv(tep[3][2]); glVertex3fv(ep[3][2]);
glNormal3fv(en[4][2]); glTexCoord2fv(tep[4][2]); glVertex3fv(ep[4][2]);
glNormal3fv(en[3][3]); glTexCoord2fv(tep[3][3]); glVertex3fv(ep[3][3]);
glNormal3fv(en[4][3]); glTexCoord2fv(tep[4][3]); glVertex3fv(ep[4][3]);
glNormal3fv(en[3][4]); glTexCoord2fv(tep[3][4]); glVertex3fv(ep[3][4]);
glNormal3fv(en[4][4]); glTexCoord2fv(tep[4][4]); glVertex3fv(ep[4][4]);
glNormal3fv(en[3][5]); glTexCoord2fv(tep[3][5]); glVertex3fv(ep[3][5]);
glNormal3fv(en[4][5]); glTexCoord2fv(tep[4][5]); glVertex3fv(ep[4][5]);
glNormal3fv(en[3][6]); glTexCoord2fv(tep[3][6]); glVertex3fv(ep[3][6]);
glNormal3fv(en[4][6]); glTexCoord2fv(tep[4][6]); glVertex3fv(ep[4][6]);
glNormal3fv(en[3][7]); glTexCoord2fv(tep[3][7]); glVertex3fv(ep[3][7]);
glNormal3fv(en[4][7]); glTexCoord2fv(tep[4][7]); glVertex3fv(ep[4][7]);
glNormal3fv(en[3][8]); glTexCoord2fv(tep[3][8]); glVertex3fv(ep[3][8]);
glNormal3fv(en[4][8]); glTexCoord2fv(tep[4][8]); glVertex3fv(ep[4][8]);
glEnd();
glBegin(GL_TRIANGLE_STRIP);
glNormal3fv(en[4][0]); glTexCoord2fv(tep[4][0]); glVertex3fv(ep[4][0]);
glNormal3fv(en[5][0]); glTexCoord2fv(tep[5][0]); glVertex3fv(ep[5][0]);
glNormal3fv(en[4][1]); glTexCoord2fv(tep[4][1]); glVertex3fv(ep[4][1]);
glNormal3fv(en[5][1]); glTexCoord2fv(tep[5][1]); glVertex3fv(ep[5][1]);
glNormal3fv(en[4][2]); glTexCoord2fv(tep[4][2]); glVertex3fv(ep[4][2]);
glNormal3fv(en[5][2]); glTexCoord2fv(tep[5][2]); glVertex3fv(ep[5][2]);
glNormal3fv(en[4][3]); glTexCoord2fv(tep[4][3]); glVertex3fv(ep[4][3]);
glNormal3fv(en[5][3]); glTexCoord2fv(tep[5][3]); glVertex3fv(ep[5][3]);
glNormal3fv(en[4][4]); glTexCoord2fv(tep[4][4]); glVertex3fv(ep[4][4]);
glNormal3fv(en[5][4]); glTexCoord2fv(tep[5][4]); glVertex3fv(ep[5][4]);
glNormal3fv(en[4][5]); glTexCoord2fv(tep[4][5]); glVertex3fv(ep[4][5]);
glNormal3fv(en[5][5]); glTexCoord2fv(tep[5][5]); glVertex3fv(ep[5][5]);
glNormal3fv(en[4][6]); glTexCoord2fv(tep[4][6]); glVertex3fv(ep[4][6]);
glNormal3fv(en[5][6]); glTexCoord2fv(tep[5][6]); glVertex3fv(ep[5][6]);
glNormal3fv(en[4][7]); glTexCoord2fv(tep[4][7]); glVertex3fv(ep[4][7]);
glNormal3fv(en[5][7]); glTexCoord2fv(tep[5][7]); glVertex3fv(ep[5][7]);
glNormal3fv(en[4][8]); glTexCoord2fv(tep[4][8]); glVertex3fv(ep[4][8]);
glNormal3fv(en[5][8]); glTexCoord2fv(tep[5][8]); glVertex3fv(ep[5][8]);
glEnd();
glBegin(GL_TRIANGLE_STRIP);
glNormal3fv(en[5][0]); glTexCoord2fv(tep[5][0]); glVertex3fv(ep[5][0]);
glNormal3fv(en[6][0]); glTexCoord2fv(tep[6][0]); glVertex3fv(ep[6][0]);
glNormal3fv(en[5][1]); glTexCoord2fv(tep[5][1]); glVertex3fv(ep[5][1]);
glNormal3fv(en[6][1]); glTexCoord2fv(tep[6][1]); glVertex3fv(ep[6][1]);
glNormal3fv(en[5][2]); glTexCoord2fv(tep[5][2]); glVertex3fv(ep[5][2]);
glNormal3fv(en[6][2]); glTexCoord2fv(tep[6][2]); glVertex3fv(ep[6][2]);
glNormal3fv(en[5][3]); glTexCoord2fv(tep[5][3]); glVertex3fv(ep[5][3]);
glNormal3fv(en[6][3]); glTexCoord2fv(tep[6][3]); glVertex3fv(ep[6][3]);
glNormal3fv(en[5][4]); glTexCoord2fv(tep[5][4]); glVertex3fv(ep[5][4]);
glNormal3fv(en[6][4]); glTexCoord2fv(tep[6][4]); glVertex3fv(ep[6][4]);
glNormal3fv(en[5][5]); glTexCoord2fv(tep[5][5]); glVertex3fv(ep[5][5]);
glNormal3fv(en[6][5]); glTexCoord2fv(tep[6][5]); glVertex3fv(ep[6][5]);
glNormal3fv(en[5][6]); glTexCoord2fv(tep[5][6]); glVertex3fv(ep[5][6]);
glNormal3fv(en[6][6]); glTexCoord2fv(tep[6][6]); glVertex3fv(ep[6][6]);
glNormal3fv(en[5][7]); glTexCoord2fv(tep[5][7]); glVertex3fv(ep[5][7]);
glNormal3fv(en[6][7]); glTexCoord2fv(tep[6][7]); glVertex3fv(ep[6][7]);
glNormal3fv(en[5][8]); glTexCoord2fv(tep[5][8]); glVertex3fv(ep[5][8]);
glNormal3fv(en[6][8]); glTexCoord2fv(tep[6][8]); glVertex3fv(ep[6][8]);
glEnd();
glEndList();
}
static void Bend_forward(void)
{
glTranslatef(0.0, 1.0, 0.0);
glRotatef(90.0, 1, 0, 0);
glTranslatef(0.0, -1.0, 0.0);
}
static void Bend_left(void)
{
glRotatef(-90.0, 0, 0, 1);
glTranslatef(0.0, 1.0, 0.0);
glRotatef(90.0, 1, 0, 0);
glTranslatef(0.0, -1.0, 0.0);
}
static void Bend_right(void)
{
glRotatef(90.0, 0, 0, 1);
glTranslatef(0.0, 1.0, 0.0);
glRotatef(90.0, 1, 0, 0);
glTranslatef(0.0, -1.0, 0.0);
}
static void Build_logo(void)
{
glNewList(logo, GL_COMPILE);
glTranslatef(5.5, -3.5, 4.5);
glTranslatef(0.0, 0.0, -7.0);
glIndexi(GRAY);
glColor3f(1, 0, 0);
glCallList(doubleCylinder);
Bend_forward();
glColor3f(0, 1, 0);
glCallList(elbow);
glTranslatef(0.0, 0.0, -7.0);
glColor3f(1, 0, 0);
glCallList(doubleCylinder);
Bend_forward();
glColor3f(0, 1, 0);
glCallList(elbow);
glTranslatef(0.0, 0.0, -5.0);
glColor3f(1, 1, 0);
glCallList(singleCylinder);
Bend_right();
glColor3f(0, 1, 0);
glCallList(elbow);
glTranslatef(0.0, 0.0, -7.0);
glColor3f(1, 0, 0);
glCallList(doubleCylinder);
Bend_forward();
glColor3f(0, 1, 0);
glCallList(elbow);
glTranslatef(0.0, 0.0, -7.0);
glColor3f(1, 0, 0);
glCallList(doubleCylinder);
Bend_forward();
glColor3f(0, 1, 0);
glCallList(elbow);
glTranslatef(0.0, 0.0, -5.0);
glColor3f(1, 1, 0);
glCallList(singleCylinder);
Bend_left();
glColor3f(0, 1, 0);
glCallList(elbow);
glTranslatef(0.0, 0.0, -7.0);
glColor3f(1, 0, 0);
glCallList(doubleCylinder);
Bend_forward();
glColor3f(0, 1, 0);
glCallList(elbow);
glTranslatef(0.0, 0.0, -7.0);
glColor3f(1, 0, 0);
glCallList(doubleCylinder);
Bend_forward();
glColor3f(0, 1, 0);
glCallList(elbow);
glTranslatef(0.0, 0.0, -5.0);
glColor3f(1, 1, 0);
glCallList(singleCylinder);
Bend_right();
glColor3f(0, 1, 0);
glCallList(elbow);
glTranslatef(0.0, 0.0, -7.0);
glColor3f(1, 0, 0);
glCallList(doubleCylinder);
Bend_forward();
glColor3f(0, 1, 0);
glCallList(elbow);
glTranslatef(0.0, 0.0, -7.0);
glColor3f(1, 0, 0);
glCallList(doubleCylinder);
Bend_forward();
glColor3f(0, 1, 0);
glCallList(elbow);
glTranslatef(0.0, 0.0, -5.0);
glColor3f(1, 1, 0);
glCallList(singleCylinder);
Bend_left();
glColor3f(0, 1, 0);
glCallList(elbow);
glTranslatef(0.0, 0.0, -7.0);
glColor3f(1, 0, 0);
glCallList(doubleCylinder);
Bend_forward();
glColor3f(0, 1, 0);
glCallList(elbow);
glTranslatef(0.0, 0.0, -7.0);
glColor3f(1, 0, 0);
glCallList(doubleCylinder);
Bend_forward();
glColor3f(0, 1, 0);
glCallList(elbow);
glTranslatef(0.0, 0.0, -5.0);
glColor3f(1, 1, 0);
glCallList(singleCylinder);
Bend_right();
glColor3f(0, 1, 0);
glCallList(elbow);
glTranslatef(0.0, 0.0, -7.0);
glColor3f(1, 0, 0);
glCallList(doubleCylinder);
Bend_forward();
glColor3f(0, 1, 0);
glCallList(elbow);
glTranslatef(0.0, 0.0, -7.0);
glColor3f(1, 0, 0);
glCallList(doubleCylinder);
Bend_forward();
glColor3f(0, 1, 0);
glCallList(elbow);
glTranslatef(0.0, 0.0, -5.0);
glColor3f(1, 1, 0);
glCallList(singleCylinder);
Bend_left();
glColor3f(0, 1, 0);
glCallList(elbow);
glEndList();
}
static void Build_lists(void)
{
singleCylinder = glGenLists(1);
doubleCylinder = glGenLists(1);
elbow = glGenLists(1);
logo = glGenLists(1);
Build_single_cylinder();
Build_double_cylinder();
Build_elbow();
Build_logo();
}
static void Init(void)
{
static float ambient[] = {0.1, 0.1, 0.1, 1.0};
static float diffuse[] = {0.5, 1.0, 1.0, 1.0};
static float position[] = {90.0, 90.0, 150.0, 0.0};
static float front_mat_shininess[] = {30.0};
static float front_mat_specular[] = {0.2, 0.2, 0.2, 1.0};
static float front_mat_diffuse[] = {0.5, 0.28, 0.38, 1.0};
static float back_mat_shininess[] = {50.0};
static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
static float lmodel_twoside[] = {GL_TRUE};
glFrontFace(GL_CW);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90, 1.0, 1.0, 200.0);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearStencil(0);
glClearAccum(0,0,0,0);
glViewport(0, 0, W, H);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT0, GL_POSITION, position);
glMaterialfv(GL_FRONT, GL_SHININESS, front_mat_shininess);
glMaterialfv(GL_FRONT, GL_SPECULAR, front_mat_specular);
glMaterialfv(GL_FRONT, GL_DIFFUSE, front_mat_diffuse);
glMaterialfv(GL_BACK, GL_SHININESS, back_mat_shininess);
glMaterialfv(GL_BACK, GL_SPECULAR, back_mat_specular);
glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_CLIP_PLANE0);
if (rgb) {
static float fog_color[] = {0.0, 0.0, 0.0, 1.0};
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, decal);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, repeat);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, repeat);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, nearest);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, nearest);
glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth, checkImageHeight, 0,
GL_RGB, GL_UNSIGNED_BYTE, checkImage);
glEnable(GL_TEXTURE_2D);
texturing = 1;
glEnable(GL_CULL_FACE);
culling = 1;
glCullFace(GL_BACK);
cullface = GL_BACK;
glFogf(GL_FOG_END, 20.0);
glFogf(GL_FOG_START, 2.0);
glFogi(GL_FOG_MODE, GL_LINEAR);
glFogfv(GL_FOG_COLOR, fog_color);
}
Build_lists();
}
GLfloat newMatrix[16] = {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
};
static void xformViewport(int vpx, int vpy, int vpw, int vph)
{
GLfloat origMatrix[16];
GLfloat halfwidth, halfheight, xcenter, ycenter;
int i;
glEnable(GL_SCISSOR_TEST);
glScissor(vpx, vpy, vpw, vph);
/*
** In the general case, we have to push the viewport out half of the
** width of a line and the farthest distance which a DrawPixels or
** consecutive glBitmap calls might move.
**
** For now, we push the viewport out a distance of one because there are
** no Bitmap rendering calls in the inner loop, and lines are always a
** width of one.
*/
for (i=0; i<1; i++) {
if (vpx > 0) {
vpx--;
vpw++;
}
if (vpy > 0) {
vpy--;
vph++;
}
if (vpx + vpw < W) {
vpw++;
}
if (vpy + vph < H) {
vph++;
}
}
glViewport(vpx, vpy, vpw, vph);
glGetFloatv(GL_PROJECTION_MATRIX, origMatrix);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
halfwidth = vpw / 2.0;
halfheight = vph / 2.0;
xcenter = vpx + halfwidth;
ycenter = vpy + halfheight;
newMatrix[0] = 1 / halfwidth;
newMatrix[5] = 1 / halfheight;
newMatrix[12] = -xcenter / halfwidth;
newMatrix[13] = -ycenter / halfheight;
glMultMatrixf(newMatrix);
newMatrix[0] = W / 2.0;
newMatrix[5] = H / 2.0;
newMatrix[12] = W / 2.0;
newMatrix[13] = H / 2.0;
glMultMatrixf(newMatrix);
glMultMatrixf(origMatrix);
}
static void unxformViewport(int vpx, int vpy, int vpw, int vph)
{
glDisable(GL_SCISSOR_TEST);
glViewport(0, 0, W, H);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
}
static void DrawIt(void)
{
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(0, 0, zTranslation);
glRotatef(30.0, 1, 0, 0);
glRotatef(yRotation, 0, 1, 0);
glClipPlane(GL_CLIP_PLANE0, plane);
if (decimation == 1) {
glCallList(logo);
} else {
int i, j;
int vpx, vpy, vpw, vph;
for (i=decimation-1; i>=0; i--) {
for (j=0; j<decimation; j++) {
vpx = i*W/decimation;
vpw = (i+1)*W/decimation - vpx;
vpy = j*H/decimation;
vph = (j+1)*H/decimation - vpy;
if (vpw > 0 && vph > 0) {
xformViewport(vpx, vpy, vpw, vph);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glCallList(logo);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
unxformViewport(vpx, vpy, vpw, vph);
}
}
}
}
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
#define NUM_SAMPLES 6
static float jitter[NUM_SAMPLES][2] = {
0.693609,0.450580, 0.306164,0.949401, 0.041299,0.249607,
0.959197,0.750780, 0.693563,0.050253, 0.306169,0.549378,
};
void jitterWindow(float x, float y)
{
GLfloat matrix[16];
/* Jitter projection matrix */
glMatrixMode(GL_PROJECTION);
glGetFloatv(GL_PROJECTION_MATRIX, matrix);
glLoadIdentity();
glTranslatef(2*x/W, 2*y/H, 0);
glMultMatrixf(matrix);
}
static void feedbackVert(GLint *count, GLint total)
{
int i;
int valuesLeft;
int valuesNeeded;
i = *count;
valuesLeft = total-i-1;
if (texturing) {
valuesNeeded=11;
} else {
valuesNeeded=7;
}
/*
** Data stored in feedbackBuf:
** i+1 - location (x,y,z)
** i+4 - color (r,g,b,a)
** i+7 - texture coords (s,t,r,q)
*/
if (valuesLeft >= valuesNeeded) {
glColor4fv(feedbackBuf+i+4);
if (texturing) {
glTexCoord4fv(feedbackBuf+i+8);
}
glVertex3fv(feedbackBuf+i+1);
i += valuesNeeded;
} else {
i = total;
}
*count = i;
}
static void DoDisplay(void)
{
GLint i, max;
if (jittering) max = NUM_SAMPLES;
else max = 1;
if (jittering) {
glClear(GL_ACCUM_BUFFER_BIT);
}
for (i=0; i<max; i++) {
if (jittering) {
glMatrixMode(GL_PROJECTION);
glPushMatrix();
jitterWindow(jitter[i][0]-0.5, jitter[i][1]-0.5);
}
glClear(clearMask);
if (capping) {
glStencilFunc(GL_ALWAYS, 1, 1);
glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
}
if (feedbackmode) {
if (texturing) {
glFeedbackBuffer(MAX_FEED, GL_3D_COLOR_TEXTURE, feedbackBuf);
} else {
glFeedbackBuffer(MAX_FEED, GL_3D_COLOR, feedbackBuf);
}
(void) glRenderMode(GL_FEEDBACK);
}
DrawIt();
if (capping) {
if (clipPlane) glDisable(GL_CLIP_PLANE0);
if (lighting) glDisable(GL_LIGHTING);
if (culling) glDisable(GL_CULL_FACE);
if (texturing) glDisable(GL_TEXTURE_2D);
if (rgb) {
glColor3f(1.0,1.0,1.0);
} else {
glIndexf(7);
}
glStencilFunc(GL_EQUAL, 1, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(0, 0, zTranslation);
glRotatef(30.0, 1, 0, 0);
glRotatef(yRotation, 0, 1, 0);
glBegin(GL_QUADS);
glVertex3f( 10, 10, 10+plane[3]);
glVertex3f(-10, 10, -10+plane[3]);
glVertex3f(-10, -10, -10+plane[3]);
glVertex3f( 10, -10, 10+plane[3]);
glEnd();
glPopMatrix();
if (texturing) glEnable(GL_TEXTURE_2D);
if (culling) glEnable(GL_CULL_FACE);
if (lighting) glEnable(GL_LIGHTING);
if (clipPlane) glEnable(GL_CLIP_PLANE0);
}
if (jittering) {
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glAccum(GL_ACCUM, 1.0/max);
}
}
if (feedbackmode) {
GLint things;
GLint token;
GLint n;
things = glRenderMode(GL_RENDER);
if (things < 0) things = MAX_FEED;
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, W, 0, H, 1, -1);
if (clipPlane) glDisable(GL_CLIP_PLANE0);
if (lighting) glDisable(GL_LIGHTING);
if (culling) glDisable(GL_CULL_FACE);
if (capping) glDisable(GL_STENCIL_TEST);
for (i=0; i<things; i++) {
token = feedbackBuf[i];
switch(token) {
case GL_POLYGON_TOKEN:
glBegin(GL_POLYGON);
i++;
if (i != things) {
n = feedbackBuf[i];
while (n--) {
feedbackVert(&i, things);
}
}
glEnd();
break;
case GL_LINE_TOKEN:
case GL_LINE_RESET_TOKEN:
glBegin(GL_LINES);
feedbackVert(&i, things);
feedbackVert(&i, things);
glEnd();
break;
case GL_POINT_TOKEN:
glBegin(GL_POINTS);
feedbackVert(&i, things);
glEnd();
break;
default:
printf("%9.2f?\n", feedbackBuf[i]);
break;
}
}
if (capping) glEnable(GL_STENCIL_TEST);
if (culling) glEnable(GL_CULL_FACE);
if (lighting) glEnable(GL_LIGHTING);
if (clipPlane) glEnable(GL_CLIP_PLANE0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
}
if (motionblur) {
glAccum(GL_MULT, 0.7);
glAccum(GL_ACCUM, 0.3);
}
if (jittering || motionblur) {
glAccum(GL_RETURN, 1.0);
}
glFinish();
}
static void SetAntiAliasedGrayScale(void)
{
XColor *xc;
float color;
long i, j, cells;
if (indexBits < 8) return;
cells = 1 << indexBits;
xc = (XColor *) malloc(cells * sizeof(XColor));
for (i = 0; i < 16; i++) {
color = (2 * i + 1) / 32.0;
for (j = 0; j < 16; j++) {
xc[i].pixel = i * 16 + j;
xc[i].red = (color * j / 15.0) * 65535.0;
xc[i].green = xc[i].red;
xc[i].blue = xc[i].red;
xc[i].flags = DoRed | DoGreen | DoBlue;
}
}
XStoreColors(dpy, cmap, xc, cells);
free((void *) xc);
}
static void SetGrayRamp(void)
{
XColor *xc;
float color;
long i, cells;
cells = 1 << indexBits;
xc = (XColor *) malloc(cells * sizeof(XColor));
for (i = 0; i < cells; i++) {
xc[i].pixel = i;
xc[i].red = ((float)i / (float)(cells - 1)) * 65535.0;
xc[i].green = xc[i].red;
xc[i].blue = xc[i].red;
xc[i].flags = DoRed | DoGreen | DoBlue;
}
XStoreColors(dpy, cmap, xc, cells);
free((void *) xc);
}
static void Usage(void)
{
printf("Usage: tlogo [-c] [-s] [-f xfont] [-geometry WxH+X+Y\n");
printf(" -c: Run in color index mode\n");
printf(" -s: Run in single buffered mode\n");
printf(" -f: Choose a new X font to use\n");
printf(" -geometry: specify window size and location\n");
exit(-1);
}
static void LoadFont(const char *fontName)
{
XFontStruct *fontInfo;
unsigned long first, last;
/* Lookup font */
fontInfo = XLoadQueryFont(dpy, fontName);
if (fontInfo == NULL) {
fprintf(stderr, "Can't find font \"%s\"\n", fontName);
return;
}
first = fontInfo->min_char_or_byte2;
last = fontInfo->max_char_or_byte2;
fontBase = glGenLists(last+1);
if (fontBase == 0) {
fprintf(stderr, "Out of list space\n");
return;
}
glXUseXFont(fontInfo->fid, first, last-first+1, fontBase+first);
fontWidth = fontInfo->max_bounds.width;
fontHeight = fontInfo->ascent + fontInfo->descent;
}
static void ShowFrames(double start, double stop)
{
char buf[20];
sprintf(buf, "%4.1f frames/sec", 1.0 / (stop - start));
glPushAttrib(GL_ENABLE_BIT | GL_TRANSFORM_BIT);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(-0.5, W - 0.5, -0.5, H - 0.5, -1, 1);
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glDisable(GL_FOG);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CLIP_PLANE0);
glColor3f(1, 1, 1); glIndexi(WHITE);
glRasterPos2f(10, fontHeight + 10);
glListBase(fontBase);
glCallLists(strlen(buf), GL_UNSIGNED_BYTE, buf);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glPopAttrib();
}
static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
{
if ((e->type == MapNotify) && (e->xmap.window == (Window)arg)) {
return GL_TRUE;
}
return GL_FALSE;
}
double Now(void)
{
#ifdef __unix
struct tms tm;
long clk;
clk = times(&tm);
return (double)clk / (double)HZ;
#else
return 0;
#endif
}
int main(int argc, char** argv)
{
int *attrs, i, rv;
XVisualInfo *vi;
XSetWindowAttributes swa;
XSizeHints sizehints;
XEvent ev;
GLXContext cx;
GLboolean needDisplay = 1;
KeySym ks;
char buf[10];
GLboolean animate = GL_FALSE;
GLboolean showFrames = GL_FALSE;
char *geometry = NULL;
double start;
rgb = 1;
doubleBuffer = 1;
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-geometry")) {
i++;
geometry = argv[i];
if (geometry == NULL) {
Usage();
}
} else if (argv[i][0] == '-') {
switch (argv[i][1]) {
case 'c':
rgb = 0;
break;
case 's':
doubleBuffer = 0;
break;
case 'f':
if (i == argc - 1) {
Usage();
}
fontName = argv[++i];
break;
default:
Usage();
}
} else {
Usage();
}
}
if (doubleBuffer) {
if (rgb) {
attrs = RGBA_DB_attributes;
} else {
attrs = CI_DB_attributes;
}
} else {
if (rgb) {
attrs = RGBA_SB_attributes;
} else {
attrs = CI_SB_attributes;
}
}
dpy = XOpenDisplay(0);
if (!dpy) {
fprintf(stderr, "Can't connect to display \"%s\"\n", getenv("DISPLAY"));
return -1;
}
vi = glXChooseVisual(dpy, DefaultScreen(dpy), attrs);
if (!vi) {
fprintf(stderr, "No matching visual on \"%s\"\n",
getenv("DISPLAY"));
return -1;
}
cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual,
rgb ? AllocNone : AllocAll);
sizehints.flags = PPosition | PSize;
sizehints.width = W;
sizehints.height = H;
sizehints.x = 10;
sizehints.y = 10;
if(geometry) {
int flags, x, y, width, height;
flags = XParseGeometry(geometry, &x, &y,
(unsigned int *)&width,
(unsigned int *)&height);
if(WidthValue & flags) {
sizehints.flags |= USSize;
sizehints.width = width;
W = width;
}
if(HeightValue & flags) {
sizehints.flags |= USSize;
sizehints.height = height;
H = height;
}
if(XValue & flags) {
if(XNegative & flags)
x = DisplayWidth(dpy, DefaultScreen(dpy)) + x
- sizehints.width;
sizehints.flags |= USPosition;
sizehints.x = x;
}
if(YValue & flags) {
if(YNegative & flags)
y = DisplayHeight(dpy, DefaultScreen(dpy)) + y
- sizehints.height;
sizehints.flags |= USPosition;
sizehints.y = y;
}
}
swa.border_pixel = 0;
swa.colormap = cmap;
swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask;
window = XCreateWindow(dpy, RootWindow(dpy, vi->screen),
sizehints.x, sizehints.y,
sizehints.width, sizehints.height,
0, vi->depth, InputOutput, vi->visual,
CWBorderPixel|CWColormap|CWEventMask, &swa);
XSetStandardProperties(dpy, window, "tlogo test", "tlogo", None,
argv, argc, &sizehints);
XSetWMColormapWindows(dpy, window, &window, 1);
XMapWindow(dpy, window);
XIfEvent(dpy, &ev, WaitForMapNotify, (char*)window);
cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
if (!glXMakeCurrent(dpy, window, cx)) {
fprintf(stderr, "Can't make window current to context\n");
return -1;
}
if (!rgb) {
glGetIntegerv(GL_INDEX_BITS, &indexBits);
SetGrayRamp();
colorIndexes[0] = BLACK;
colorIndexes[1] = GRAY;
colorIndexes[2] = WHITE;
glMaterialiv(GL_FRONT_AND_BACK, GL_COLOR_INDEXES, colorIndexes);
}
Init();
LoadFont(fontName);
for (;;) {
while (XPending(dpy) != 0) {
XNextEvent(dpy, &ev);
switch (ev.type) {
case Expose:
needDisplay = GL_TRUE;
break;
case ConfigureNotify:
W = ev.xconfigure.width;
H = ev.xconfigure.height;
glViewport(0, 0, W, H);
needDisplay = GL_TRUE;
break;
case KeyPress:
rv = XLookupString(&ev.xkey, buf, sizeof(buf), &ks, 0);
needDisplay = GL_TRUE;
switch (ks) {
case XK_Escape:
glXDestroyContext(dpy, cx);
XCloseDisplay(dpy);
return 0;
case XK_space:
animate = !animate;
break;
case XK_question:
showFrames = !showFrames;
break;
case XK_Left:
yRotation += 0.5;
break;
case XK_Right:
yRotation -= 0.5;
break;
case XK_Up:
plane[3] += 2.0;
break;
case XK_Down:
plane[3] -= 2.0;
break;
case XK_Z:
zTranslation -= 1.0;
break;
case XK_z:
zTranslation += 1.0;
break;
case XK_1:
glPolygonMode(polymode, GL_FILL);
break;
case XK_2:
glPolygonMode(polymode, GL_POINT);
break;
case XK_3:
glPolygonMode(polymode, GL_LINE);
break;
case XK_p: case XK_P:
needDisplay = GL_FALSE;
switch (polymode) {
case GL_BACK:
polymode = GL_FRONT;
printf("Polymode now GL_FRONT\n");
break;
case GL_FRONT:
polymode = GL_FRONT_AND_BACK;
printf("Polymode now GL_FRONT_AND_BACK\n");
break;
case GL_FRONT_AND_BACK:
polymode = GL_BACK;
printf("Polymode now GL_BACK\n");
break;
}
break;
case XK_4:
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
break;
case XK_5:
glEnable(GL_POLYGON_SMOOTH);
if (rgb) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
} else {
SetAntiAliasedGrayScale();
}
break;
case XK_6:
glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
glDisable(GL_POLYGON_SMOOTH);
if (rgb) {
glBlendFunc(GL_ONE, GL_ZERO);
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
} else {
SetGrayRamp();
}
break;
case XK_7:
glPolygonStipple(stipple);
glEnable(GL_POLYGON_STIPPLE);
break;
case XK_8:
glDisable(GL_POLYGON_STIPPLE);
break;
case XK_9:
glShadeModel(GL_FLAT);
break;
case XK_0:
glShadeModel(GL_SMOOTH);
break;
case XK_Q:
glEnable(GL_CULL_FACE);
culling = 1;
glCullFace(GL_FRONT_AND_BACK);
cullface = GL_FRONT_AND_BACK;
break;
case XK_q:
glDisable(GL_CULL_FACE);
culling = 0;
break;
case XK_W: case XK_w:
glEnable(GL_CULL_FACE);
culling = 1;
glCullFace(GL_FRONT);
cullface = GL_FRONT;
break;
case XK_E: case XK_e:
glEnable(GL_CULL_FACE);
culling = 1;
glCullFace(GL_BACK);
cullface = GL_BACK;
break;
case XK_R: case XK_r:
glFrontFace(GL_CW);
break;
case XK_T: case XK_t:
glFrontFace(GL_CCW);
break;
case XK_Y: case XK_y:
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_LSB_FIRST, 0);
glPolygonStipple(stipple);
break;
case XK_U: case XK_u:
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_LSB_FIRST, 1);
glPolygonStipple(stipple);
break;
case XK_A: case XK_a:
glEnable(GL_TEXTURE_2D);
texturing = 1;
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, repeat);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, repeat);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
nearest);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
nearest);
glTexImage2D(GL_TEXTURE_2D, 0, 4, brickImageWidth,
brickImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
(const unsigned char*) brickImage);
break;
case XK_S: case XK_s:
glEnable(GL_TEXTURE_2D);
texturing = 1;
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, repeat);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, repeat);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
nearest);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
nearest);
glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth,
checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,
(const unsigned char*) checkImage);
break;
case XK_D: case XK_d:
glDisable(GL_TEXTURE_2D);
texturing = 0;
break;
case XK_F: case XK_f:
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, decal);
break;
case XK_G: case XK_g:
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, modulate);
break;
case XK_H: case XK_h:
dodither = !dodither;
dodither ? glEnable(GL_DITHER) : glDisable(GL_DITHER);
break;
case XK_L: case XK_l:
lighting = !lighting;
lighting ? glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING);
break;
case XK_K: case XK_k:
twoside = !twoside;
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, twoside);
break;
case XK_I: case XK_i:
fog = !fog;
fog ? glEnable(GL_FOG) : glDisable(GL_FOG);
break;
case XK_J: case XK_j:
depth = !depth;
if (depth) {
glEnable(GL_DEPTH_TEST);
clearMask |= GL_DEPTH_BUFFER_BIT;
} else {
glDisable(GL_DEPTH_TEST);
clearMask &= ~GL_DEPTH_BUFFER_BIT;
}
break;
case XK_X: case XK_x:
clipPlane = !clipPlane;
if (clipPlane)
glEnable(GL_CLIP_PLANE0);
else
glDisable(GL_CLIP_PLANE0);
break;
case XK_C: case XK_c:
capping = !capping;
if (capping) {
clearMask |= GL_STENCIL_BUFFER_BIT;
glEnable(GL_STENCIL_TEST);
} else {
clearMask &= ~GL_STENCIL_BUFFER_BIT;
glDisable(GL_STENCIL_TEST);
}
break;
case XK_V: case XK_v:
jittering = 1-jittering;
if (motionblur) motionblur = 0;
if (feedbackmode) feedbackmode = 0;
break;
case XK_B: case XK_b:
motionblur = 1-motionblur;
if (motionblur) {
glClear(GL_ACCUM_BUFFER_BIT);
}
if (jittering) jittering = 0;
break;
case XK_N: case XK_n:
feedbackmode = 1-feedbackmode;
if (jittering) jittering = 0;
break;
case XK_M:
decimation--;
if (decimation < 1) decimation = 1;
break;
case XK_m:
decimation++;
break;
default:
needDisplay = GL_FALSE;
break;
}
break;
}
}
if (needDisplay || animate) {
if (animate) {
yRotation += 0.5;
}
if (showFrames) {
start = Now();
}
DoDisplay();
if (doubleBuffer) {
glXSwapBuffers(dpy, window);
}
if (showFrames) {
if (doubleBuffer) glDrawBuffer(GL_FRONT);
ShowFrames(start, Now());
if (doubleBuffer) glDrawBuffer(GL_BACK);
}
needDisplay = GL_FALSE;
}
if (!animate) {
XPeekEvent(dpy, &ev);
}
}
}